using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;

namespace Tomahawk.Runtime.Input.Pattern
{
    /// <summary>
    /// Event raised when one pattern is matched
    /// </summary>
    /// <param name="patternName">The pattern name matched</param>
    /// <param name="gameTime">The time when the pattern is matched</param>
    public delegate void PatternsMatchedMethod(string patternName);

    /// <summary>
    /// All the patterns to match
    /// </summary>
    public class GamePadPatterns
    {
        /// <summary>
        /// The object to store all the patterns
        /// </summary>
        private Dictionary<string, GamePadPattern> patterns = new Dictionary<string,GamePadPattern>();

        /// <summary>
        /// Event raised when a pattern is matched
        /// </summary>
        public event PatternsMatchedMethod OnPatternsMatched;

        /// <summary>
        /// Add a pattern to match. ArgumentException is throwed when the key already exist
        /// </summary>
        /// <param name="pattern">the pattern to add</param>
        internal void AddPattern(GamePadPattern pattern)
        {
            patterns.Add(pattern.Name, pattern);
        }

        /// <summary>
        /// Get a pattern by its name
        /// </summary>
        /// <param name="patternName">The name of the pattern</param>
        /// <returns></returns>
        internal GamePadPattern GetPattern(string patternName)
        {
            GamePadPattern p;
            if (!patterns.TryGetValue(patternName, out p))
            {
                throw new System.Collections.Generic.KeyNotFoundException("Cannot get the '" + patternName + "' pattern");
            }
            return p;
        }

        /// <summary>
        /// Try to match all the stored patterns
        /// </summary>
        /// <param name="player">The player to test. It's useful when the event OnPatternsMatched</see> is raised</param>
        /// <param name="state">The state of the player</param>
        /// <param name="gameTime">The time when the match is done. It's useful when the event <see cref="OnPatternsMatched"></see> is raised</param>
        internal void Match(GamePadState state, float elapsedTotalTime)
        {
            bool matched = false;

            foreach( KeyValuePair<string, GamePadPattern> pattern in patterns )
            {
                matched = pattern.Value.Match(state, elapsedTotalTime);
                if(matched && OnPatternsMatched != null){
                    OnPatternsMatched(pattern.Key);
                }
            }
        }

        /// <summary>
        /// Load a gamepad pattern to the patterns system
        /// </summary>
        /// <param name="patternTemplate">The xml pattern template to load</param>
        /// <returns>Returns the pattern created. It's useful for capturing events</returns>
        public GamePadPattern Load(string patternTemplate)
        {
            GamePadPattern p = new GamePadPattern();

            //Load the info of the pattern from the xml
            p.Load(patternTemplate, Engine.Instance.InputManager.Pads.XmlContentManager);

            //add the pattern to the list of patterns
            AddPattern(p);
            return p;
        }

        public void Destroy(GamePadPattern p)
        {
            this.patterns.Remove(p.Name);
            p.Destroy();
        }

    }

}
